package cz.proks.easyhelpdesk.gae.api.impl.db;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import cz.proks.easyhelpdesk.api.UserApi;
import cz.proks.easyhelpdesk.api.config.Configuration;
import cz.proks.easyhelpdesk.api.exception.ApiException;
import cz.proks.easyhelpdesk.api.model.User;
import cz.proks.easyhelpdesk.gae.api.impl.dbo.HelpdeskMember;

@Repository(Configuration.DB.USER_API)
@Scope("prototype")
public class UserApiImpl extends BaseApiImpl<User> implements UserApi {
	private final Logger log = LoggerFactory.getLogger(getClass());

	@Override
	protected Class<User> getDomainClass() {
		return User.class;
	}

    @Override
    protected User getDboObject(User entity) {
        cz.proks.easyhelpdesk.gae.api.impl.dbo.User dbo = instantiateDbo(entity);

        if (dbo != null)
            dbo.toDbo(entity);

        return dbo;
    }

    @Override    
    @Transactional(readOnly = true)
    public User getForProvider(String providerId) throws ApiException {
        log.debug("getForProvider():: Start with providerId '{}'", providerId);
        
        Query query = getEntityManager().createNamedQuery("User.getForProvider");
        query.setParameter("providerId", providerId);        
        
        User user = null;
        
        try {
            cz.proks.easyhelpdesk.gae.api.impl.dbo.User dbo = (cz.proks.easyhelpdesk.gae.api.impl.dbo.User) query.getSingleResult();
            user = fromDbo(dbo);
        } catch (NoResultException nre) {
            // NOP
        }
        
        log.debug("getForProvider():: Exit with entity '{}'", user);
        return user;
    }		    
    
    @Override
    @Transactional(readOnly = true)
    public List<User> listForHelpdesk(Long helpdeskId) throws ApiException {
        log.debug("listForHelpdesk():: Start with helpdeskId '{}'", helpdeskId);
        
        Query queryHM = getEntityManager().createNamedQuery("HelpdeskMember.listForHelpdesk");
        queryHM.setParameter("helpdeskId", helpdeskId);
        List<HelpdeskMember> dboHelpdeskMembers = queryHM.getResultList();
        
        List<Long> userIds = new LinkedList<Long>();
        if (dboHelpdeskMembers != null)
            for (HelpdeskMember dboHelpdeskMember : dboHelpdeskMembers)
                userIds.add(dboHelpdeskMember.getUserId());
        
        Query query = getEntityManager().createNamedQuery("User.listForHelpdesk");
        query.setParameter("userIds", userIds);        
        
        List<User> users = new LinkedList<User>();
        
        if (!userIds.isEmpty())
            try {
                List<cz.proks.easyhelpdesk.gae.api.impl.dbo.User>  dboList = query.getResultList();
                users.addAll(fromDboList(dboList));
            } catch (EmptyResultDataAccessException erdae) {
                // NOP
            }
        
        log.debug("listForHelpdesk():: Exit with {}", (users == null ? "null list" : "list of " + users.size() + " members"));
        return users;
    }            
}
